package com.spring.factory.impl;

import com.spring.factory.BeanFactory;
import com.spring.factory.ObjectFactory;

public abstract class AbstractBeanFactory extends SingletonObjects implements BeanFactory {
	
	// 核心方法,getBean()
	@Override
	public Object getBean(String name) {
		return doGetBean(name);
	}
	
	@Override
	@SuppressWarnings("unchecked")
	public <T> T getBean(String name, Class<T> clazz) {
		return (T) getBean(name);
	}
	
	
	/**
	 * 核心的获取bean 逻辑：可能直接从单例池返回，也可能对象暂时不存在，需要创建后返回
	 * 返回的bean 可能是完成品，也可能是半成品
	 *
	 * 注意是获取逻辑，创建逻辑丢给子类实现
	 *
	 * @param beanName bean名字
	 */
	@SuppressWarnings("unchecked")
	private <T> T doGetBean(String beanName) {
		Object singleton = getSingletonObject(beanName);
		if (singleton != null) {
			return (T) singleton;
		}
		// 一级缓存没有，就要检查下未创建还是创建中
		if (isInCreating(beanName)) {
			// 正在创建中 ，就尝试从二级缓存查找
			singleton = getEarlySingletonObject(beanName);
			if (singleton == null) {
				
				// 二级缓存都没有，就找下三级缓存
				ObjectFactory<?> objectFactory = getObjectFactory(beanName);
				// 执行缓存的工厂方法逻辑，得到暴露出来的对象
				singleton = objectFactory.getObject();
				
				// 删除3级缓存，移动到二级缓存
				removeObjectFactory(beanName);
				addEarlyObject(beanName, singleton);
			}
			// 这里直接将 二级缓存的早期对象返回出去
			return (T) singleton;
		} else {
			// 走下创建逻辑
			return (T) createBean(beanName);
		}
	}
	
	// 丢给子类实现
	protected abstract Object createBean(String beanName);
}
